<template>
  <div class="pl-2">
    <div v-for="item in children" :key="item.id" class="tree-node">
      <div
        @dragstart="dragstart(item)"
        @drop="drop(item)"
        @dragenter="dragenter(item)"
        class="tree-title pr-2 border-1 flex align-center flex-nowrap justify-between my-4"
        @click="onSelect(item)"
        @contextmenu="menuEvent(item)"
        :draggable="!item.editable"
        :class="[{ active: treeBus.id === item.id }]"
        @dblclick="item.expand = !item.expand"
      >
        <div class="flex align-center flex-nowrap" @click.left.stop="false">
          <CaretDownOutlined
            @click="item.expand = !item.expand"
            class="mx-2 text-12"
            v-if="item.type === 'folder' && item.expand"
          />
          <CaretRightOutlined
            @click="item.expand = !item.expand"
            class="mx-2 text-12"
            v-else-if="item.type === 'folder'"
          />

          <file-outlined v-if="item.type === 'file'" class="mx-2 text-12" />

          <borderless-table-outlined class="mx-2 text-8" v-else-if="item.type === 'props'" />
          <div v-if="!item.editable" class="flex align-center" @click="onSelect(item)">
            <a-tooltip>
              <template #title>
                <span class="tree-title-text">{{ item.title }}</span>
              </template>
              <div class="tree-title-text">{{ item.title }}</div>
            </a-tooltip>
          </div>
          <!-- 编辑区 -->
          <div v-else>
            <input
              @keydown.enter="comfirmEdit(item)"
              v-model="item.title"
              v-focus
              @blur="comfirmEdit(item)"
            />
            <check-outlined class="ml-4 text-primary" @click="item.editable = false" />
          </div>
        </div>
        <div class="actions" v-if="!item.editable" @click.stop="false">
          <a-tooltip>
            <template #title>编辑文件名</template>
            <edit-outlined @click="edit(item)" />
          </a-tooltip>
          <a-tooltip>
            <template #title>添加属性</template>
            <PlusOutlined  class="mx-4" @click="addProp(item.children, item)" />
          </a-tooltip>
          <a-popconfirm
            title="如果该目录下有其他子元素,也会一并删除"
            ok-text="确定"
            cancel-text="取消"
            @confirm="deleteItem(item)"
          >
            <delete-outlined style="color: #fb6f92" />
          </a-popconfirm>
        </div>
      </div>
      <Subtree :data="item.children" v-if="item.expand" />
    </div>
    <InContextmenu
      :data="menu.data"
      v-if="menu.show"
      :event="menu.event"
      @onClose="menu.show = false"
    />
  </div>
</template>
<script lang="ts">
export default {
  name: "Subtree",
  components: { PlusOutlined, CaretRightOutlined, CaretDownOutlined }
};
</script>
<script setup lang="ts">
import { fileConfig, folderConfig, propConfig } from "@/data/config";
import {
  activeItem,
  deleteSelf,
  moveDown,
  moveToBottom,
  moveToTop,
  moveUp
} from "@/store/utils/project";
import { treeType, contextmenuData, contextmenuType } from "@/types/project";
import { downloadText, formatCode, uuid } from "@/utils/utils";
import {
  DeleteOutlined,
  FolderOutlined,
  FileOutlined,
  EyeOutlined,
  CompressOutlined,
  FormatPainterOutlined,
  OrderedListOutlined,
  CopyOutlined,
  PlusOutlined,
  ExportOutlined,
  CaretRightOutlined,
  CaretDownOutlined,
  InteractionOutlined,
  FileAddOutlined
} from "@ant-design/icons-vue";
import { message } from "ant-design-vue";
import { computed, ref } from "vue";
import { pasteCopyInfo, setConfigMode, setCopyInfo } from "../bus/bin";
import { showCompiledCode, showSourceCode, showUI } from "../bus/source";
import { setProp, setPropList, treeBus } from "../bus/treeData";
import InContextmenu from "../components/InContextmenu.vue";
const props = defineProps({
  data: Array<treeType>
});
const dragstart = (item: treeType) => {
  const e = window.event as DragEvent;
  var data = formatCode(item);
  e.dataTransfer?.setData("data", data);
};
const dragenter = (item: treeType) => {
  // item.expand = true;
};
/* 放下的文件 */
const drop = (item: treeType) => {
  const e = window.event as DragEvent;
  /* 拖过来的文件 */
  var target = JSON.parse(e.dataTransfer?.getData("data") as any) as treeType;

  if (item.type === "file") return;
  item.expand = true;
  if (target.id === item.id) {
    return;
  }

  /* 当放下的是文件夹，才能拖拽 */
  if (item.type === "folder") {
    deleteSelf(target);
    target.id = uuid();
    var _item = JSON.parse(JSON.stringify(target));
    item.children.unshift(_item);
  }
};
/* 公共右键菜单 */
const menu = ref<contextmenuType>({
  data: [],
  show: false,
  tempData: null,
  event: undefined
});

/* 公共菜单属性 */
let commonMenu = [
  {
    text: "复制",
    event() {
      setCopyInfo(menu.value.tempData);
    },
    icon: CopyOutlined
  },
  {
    text: "粘贴",
    event() {
      pasteCopyInfo();
    },
    icon: FileAddOutlined
  },
  {
    text: "导出",
    event() {
      downloadText(formatCode(treeBus.selectItem));
    },
    icon: ExportOutlined
  },
  {
    text: "移动",
    event() {},
    icon: InteractionOutlined,
    children: [
      {
        text: "移动到顶部",
        event() {
          var parent = menu.value.tempData;
          moveToTop(parent);
        },
        icon: FileOutlined
      },
      {
        text: "移动到底部",
        event() {
          var parent = menu.value.tempData;
          moveToBottom(parent);
        },
        icon: FileOutlined
      },
      {
        text: "上移一层",
        event() {
          var parent = menu.value.tempData;
          moveUp(parent);
        },
        icon: FileOutlined
      },
      {
        text: "下移一层",
        event() {
          var parent = menu.value.tempData;
          moveDown(parent);
        },
        icon: FileOutlined
      }
    ]
  },
  {
    text: "代码预览",
    event() {},
    icon: CompressOutlined,
    children: [
      {
        text: "源码预览",
        event() {
          viewSourceCode();
        },
        icon: EyeOutlined
      },
      {
        text: "转编预览",
        event() {
          viewCompiledCode();
        },
        icon: CompressOutlined
      }
    ]
  },
  {
    text: "删除该项",
    event() {
      deleteSelf(menu.value.tempData);
    },
    icon: DeleteOutlined
  }
];
/* 文件夹的菜单的数据 */
const folderMenuData = ref([
  {
    text: "新建属性",
    event() {
      var parent = menu.value.tempData; /* 将自己作为父级，往里面添加子元素 */
      addNewProp(parent);
    },
    icon: FileOutlined
  },
  ...commonMenu,
  {
    text: "新建",
    event() {},
    icon: OrderedListOutlined,
    children: [
      {
        text: "新建文件夹",
        event() {
          var parent = menu.value.tempData;
          addNewFolder(parent);
        },
        icon: FolderOutlined
      },
      {
        text: "新建文件",
        event() {
          var parent = menu.value.tempData;
          addNewFile(parent);
        },
        icon: FolderOutlined
      }
    ]
  },

  {
    text: "可视化预览",
    event() {
      viewUI();
    },
    icon: FormatPainterOutlined
  }
]);
/* 文件的菜单的数据 */
const fileMenuData = ref([
  {
    text: "可视化预览",
    event() {
      setProp(menu.value.tempData);
      showUI();
    },
    icon: FormatPainterOutlined
  },
  ...commonMenu
]);
/*属性的菜单的数据 */
const propsMenuData = ref([
  ...commonMenu,
  {
    text: "可视化预览",
    event() {
      var parent = menu.value.tempData;
      setProp(parent);
      showUI();
    },
    icon: FormatPainterOutlined
  }
]);

const viewCompiledCode = () => {
  var data = menu.value.tempData;
  showCompiledCode(data);
};
const viewSourceCode = () => {
  var data = menu.value.tempData;
  showSourceCode(data);
};
function menuEvent(item: treeType) {
  var { type } = item;
  menu.value.event = window.event as MouseEvent;
  menu.value.show = true;
  if (type === "file") {
    menu.value.data = fileMenuData.value as Array<contextmenuData>;
  } else if (type == "folder") {
    menu.value.data = folderMenuData.value;
  } else if (type === "props") {
    menu.value.data = propsMenuData.value;
  }
  menu.value.tempData = item;
  treeBus.id = item.id;
  // treeBus.selectItem = item;
}

const viewUI = () => {
  var { children } = menu.value.tempData;
  setPropList(children);
  showUI();
};

/* 数据节点 */
const children = computed(() => {
  return props.data;
});

/* 选中触发 */
const onSelect = (item: treeType & { [key: string]: any }) => {
  treeBus.id = item.id;
  treeBus.selectItem = item;
  // item.expand = !item.expand;
  setConfigMode();
  /* 当为属性的时候，展示最左侧的可视化界面 */
  // if (item.type == "props") {
  //   setProp(item);
  // }
};
/**
 *  todo 增删改查
 *
 * */
const addProp = (parent: Array<any>, item: treeType) => {
  item.expand = true;
  parent.unshift(propConfig());
};

/* 添加属性 */
const addNewProp = (parent: any) => {
  // 添加新的子项时，需要展开自己
  parent.expand = true;
  let _prop = propConfig();
  parent.children.unshift(_prop);
  treeBus.selectItem = _prop;
  treeBus.id = _prop.id;
  // setConfigMode();
};

/* 添加文件,往自己的子列表添加数据，parent为当前自身 */
const addNewFile = (parent: any) => {
  // 添加新的子项时，需要展开自己
  parent.expand = true;
  let config = fileConfig();
  treeBus.selectItem = config;
  treeBus.id = config.id;
  parent.children.unshift(config);
};

/* 添加文件夹,往自己的子列表添加数据，parent为当前自身 */
const addNewFolder = (parent: any) => {
  // 添加新的子项时，需要展开自己
  parent.expand = true;
  let config = folderConfig();
  activeItem(config);
  parent.children.unshift(config);
};

/* 删除自己 */
const deleteItem = (item: treeType) => {
  deleteSelf(item);
  message.success("成功删除");
};
/* 编辑标题 */
const edit = (item: treeType) => {
  item.editable = !item.editable;
};

/* 编辑文件校验 */
const comfirmEdit = (item: treeType) => {
  if (item.title === "") {
    deleteSelf(item);
  }
  item.editable = false;
};
</script>

<style lang="scss" scoped>
.tree-node {
  line-height: 24px;
  .actions {
    display: none;
  }
  .active {
    background-color: #4f4f4f;
    outline: 1px solid #faad14;
  }
  .tree-title {
    input {
      background-color: transparent;
      max-width: 100px;
      height: 30px;
      line-height: 30px;
      font-size: 14px;
      font-family: unset !important;
      outline: none;
      padding: 0;
      border: none;
    }
    cursor: pointer;
    &:hover {
      background-color: #4f4f4f;
      .actions {
        display: initial;
      }
    }
  }
  .text-primary {
    color: #faad14;
    border-radius: 50%;
  }
}

.tree-title-text {
  max-width: 100px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  height: 30px;
  line-height: 30px;
}
</style>
